package com.njbw.design_pattern.struct.decorator;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Constructor;

/**
 * 装饰器基类
 *
 * @author 黄侯淳
 * @since JDK 1.8
 */
@Slf4j
@Data
@AllArgsConstructor
public abstract class Decorator implements Component {

    // 装饰器涉及模式使用组合的形式进行装饰
    private final Component component;

    @Override
    public void operation() {
        component.operation();
    }

    public static Component newDecoratorInstance(Class<? extends Decorator> decoratorClass, Component base) {
        Constructor<? extends Component> decoratorConstructor = getDecoratorConstructor(decoratorClass);
        try {
            return decoratorConstructor.newInstance(base);
        } catch (Exception e) {
            log.error("Could not instantiate cache decorator ({}). Cause: {}", decoratorClass, e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    public static Constructor<? extends Component> getDecoratorConstructor(Class<? extends Decorator> decoratorClass) {
        try {
            return decoratorClass.getConstructor(Component.class);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}
